<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="./js/ctx.js"></script>
</head>
<body>
<div id="cesiumContainer">
</div>
<div id="toolbar">
    <div id="viewChanged">View Changed</div>
    <div id="cameraChanged">Camera Changed</div>
</div>
<script>
    var initCesium = new InitCesium();
    var viewer = initCesium.initViewer('cesiumContainer');
    var scene = viewer.scene;
    var clock = viewer.clock;
    var referenceFramePrimitive;

    function flyToSanDiego() {
        Sandcastle.declare(flyToSanDiego);
        viewer.camera.flyTo({
            destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
        });
    }

    function flyToHeadingPitchRoll() {
        Sandcastle.declare(flyToHeadingPitchRoll);
        viewer.camera.flyTo({
            destination : Cesium.Cartesian3.fromDegrees(-122.22, 46.12, 5000.0),
            orientation : {
                heading : Cesium.Math.toRadians(20.0),
                pitch : Cesium.Math.toRadians(-35.0),
                roll : 0.0
            }
        });
    }

    function flyToLocation() {
        Sandcastle.declare(flyToLocation);

        // Create callback for browser's geolocation
        function fly(position) {
            viewer.camera.flyTo({
                destination : Cesium.Cartesian3.fromDegrees(position.coords.longitude, position.coords.latitude, 1000.0)
            });
        }

        // Ask browser for location, and fly there.
        navigator.geolocation.getCurrentPosition(fly);
    }

    function viewRectangle() {
        Sandcastle.declare(viewRectangle);

        var west = -77.0;
        var south = 38.0;
        var east = -72.0;
        var north = 42.0;

        var rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north);
        viewer.camera.setView({
            destination: rectangle
        });

        // Show the rectangle.  Not required; just for show.
        viewer.entities.add({
            rectangle : {
                coordinates : rectangle,
                fill : false,
                outline : true,
                outlineColor : Cesium.Color.WHITE
            }
        });
    }

    function flyToRectangle() {
        Sandcastle.declare(flyToRectangle);

        var west = -90.0;
        var south = 38.0;
        var east = -87.0;
        var north = 40.0;
        var rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north);

        viewer.camera.flyTo({
            destination : rectangle
        });

        // Show the rectangle.  Not required; just for show.
        viewer.entities.add({
            rectangle : {
                coordinates : rectangle,
                fill : false,
                outline : true,
                outlineColor : Cesium.Color.WHITE
            }
        });
    }

    function setReferenceFrame() {
        Sandcastle.declare(setReferenceFrame);

        var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);
        var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

        // View in east-north-up frame
        var camera = viewer.camera;
        camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
        camera.lookAtTransform(transform, new Cesium.Cartesian3(-120000.0, -120000.0, 120000.0));

        // Show reference frame.  Not required.
        referenceFramePrimitive = scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({
            modelMatrix : transform,
            length : 100000.0
        }));
    }

    function setHeadingPitchRoll() {
        Sandcastle.declare(setHeadingPitchRoll);

        var camera = viewer.camera;
        camera.setView({
            destination : Cesium.Cartesian3.fromDegrees(-75.5847, 40.0397, 1000.0),
            orientation: {
                heading : -Cesium.Math.PI_OVER_TWO,
                pitch : -Cesium.Math.PI_OVER_FOUR,
                roll : 0.0
            }
        });
    }

    function icrf(scene, time) {
        if (scene.mode !== Cesium.SceneMode.SCENE3D) {
            return;
        }

        var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
        if (Cesium.defined(icrfToFixed)) {
            var camera = viewer.camera;
            var offset = Cesium.Cartesian3.clone(camera.position);
            var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
            camera.lookAtTransform(transform, offset);
        }
    }

    function viewInICRF() {
        Sandcastle.declare(viewInICRF);

        viewer.camera.flyHome(0);

        clock.multiplier = 3 * 60 * 60;
        scene.postUpdate.addEventListener(icrf);
        scene.globe.enableLighting = true;
    }

    var viewChanged = document.getElementById('viewChanged');

    var removeStart;
    var removeEnd;

    function cameraEvents() {
        Sandcastle.declare(cameraEvents);

        var camera = viewer.camera;
        removeStart = camera.moveStart.addEventListener(function() {
            viewChanged.style.display = 'block';
        });
        removeEnd = camera.moveEnd.addEventListener(function() {
            viewChanged.style.display = 'none';
        });
    }

    var cameraChanged = document.getElementById('cameraChanged');

    var removeChanged;

    function cameraChanges() {
        Sandcastle.declare(cameraChanges);

        var i = 0;
        removeChanged = viewer.camera.changed.addEventListener(function(percentage) {
            ++i;
            cameraChanged.innerText = 'Camera Changed: ' + i + ', ' + percentage.toFixed(6);
            cameraChanged.style.display = 'block';
        });
    }

    function flyInACity() {
        Sandcastle.declare(flyInACity);

        var camera = scene.camera;
        camera.flyTo({
            destination : Cesium.Cartesian3.fromDegrees(-73.98580932617188, 40.74843406689482, 363.34038727246224),
            complete : function() {
                setTimeout(function() {
                    camera.flyTo({
                        destination : Cesium.Cartesian3.fromDegrees(-73.98585975679403, 40.75759944127251, 186.50838555841779),
                        orientation : {
                            heading : Cesium.Math.toRadians(200.0),
                            pitch : Cesium.Math.toRadians(-50.0)
                        },
                        easingFunction : Cesium.EasingFunction.LINEAR_NONE
                    });
                }, 1000);
            }
        });
    }

    function losAngelesToTokyo(adjustPitch) {
        var camera = scene.camera;

        var tokyoOptions = {
            destination : Cesium.Cartesian3.fromDegrees(139.8148, 35.7142, 20000.0),
            orientation: {
                heading : Cesium.Math.toRadians(15.0),
                pitch : Cesium.Math.toRadians(-60),
                roll : 0.0
            },
            duration: 20,
            flyOverLongitude: Cesium.Math.toRadians(60.0)
        };

        var laOptions = {
            destination : Cesium.Cartesian3.fromDegrees(-117.729, 34.457, 10000.0),
            duration: 5,
            orientation: {
                heading : Cesium.Math.toRadians(-15.0),
                pitch : -Cesium.Math.PI_OVER_FOUR,
                roll : 0.0
            }
        };

        laOptions.complete = function() {
            setTimeout(function() {
                camera.flyTo(tokyoOptions);
            }, 1000);
        };

        if (adjustPitch) {
            tokyoOptions.pitchAdjustHeight = 1000;
            laOptions.pitchAdjustHeight = 1000;
        }

        camera.flyTo(laOptions);
    }

    function flyOverLongitude(adjustPitch) {
        Sandcastle.declare(flyOverLongitude);
        losAngelesToTokyo();
    }

    function flyOverLongitudeWithPitch() {
        Sandcastle.declare(flyOverLongitudeWithPitch);
        losAngelesToTokyo(true);
    }

    Sandcastle.addToolbarMenu([{
        text : 'Camera Options'
    }, {
        text : 'Fly in a city',
        onselect : function() {
            flyInACity();
            Sandcastle.highlight(flyInACity);
        }
    }, {
        text : 'Fly to San Diego',
        onselect : function() {
            flyToSanDiego();
            Sandcastle.highlight(flyToSanDiego);
        }
    }, {
        text : 'Fly to Location with heading, pitch and roll',
        onselect : function() {
            flyToHeadingPitchRoll();
            Sandcastle.highlight(flyToHeadingPitchRoll);
        }
    }, {
        text : 'Fly to My Location',
        onselect : function() {
            flyToLocation();
            Sandcastle.highlight(flyToLocation);
        }
    }, {
        text : 'Fly to Rectangle',
        onselect : function() {
            flyToRectangle();
            Sandcastle.highlight(flyToRectangle);
        }
    }, {
        text : 'View a Rectangle',
        onselect : function() {
            viewRectangle();
            Sandcastle.highlight(viewRectangle);
        }
    }, {
        text : 'Set camera reference frame',
        onselect : function() {
            setReferenceFrame();
            Sandcastle.highlight(setReferenceFrame);
        }
    }, {
        text : 'Set camera with heading, pitch, and roll',
        onselect : function() {
            setHeadingPitchRoll();
            Sandcastle.highlight(setHeadingPitchRoll);
        }
    }, {
        text : 'View in ICRF',
        onselect : function() {
            viewInICRF();
            Sandcastle.highlight(viewInICRF);
        }
    }, {
        text : 'Move events',
        onselect : function() {
            cameraEvents();
            Sandcastle.highlight(cameraEvents);
        }
    }, {
        text : 'Camera changed event',
        onselect : function() {
            cameraChanges();
            Sandcastle.highlight(cameraChanges);
        }
    }, {
        text : 'Fly from Los Angeles to Tokyo via Europe',
        onselect : function() {
            flyOverLongitude();
            Sandcastle.highlight(flyOverLongitude);
        }
    }, {
        text : 'Look down during exaggerated flight',
        onselect : function() {
            flyOverLongitudeWithPitch();
            Sandcastle.highlight(flyOverLongitudeWithPitch);
        }
    }
    ]);

    Sandcastle.reset = function() {
        scene.completeMorph();
        viewer.entities.removeAll();
        scene.primitives.remove(referenceFramePrimitive);
        scene.tweens.removeAll();

        if (Cesium.defined(removeStart)) {
            removeStart();
            removeEnd();

            viewChanged.style.display = 'none';

            removeStart = undefined;
            removeEnd = undefined;
        }

        if (Cesium.defined(removeChanged)) {
            removeChanged();
            removeChanged = undefined;

            cameraChanged.style.display = 'none';
        }

        viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

        clock.multiplier = 1.0;
        scene.postUpdate.removeEventListener(icrf);
        scene.globe.enableLighting = false;
    };

    scene.morphComplete.addEventListener(function() {
        Sandcastle.reset();
    });

</script>
</body>

</html>